#include <iostream>
using namespace std;
#include <cstdlib>
#include <fstream>
// 8.1内联函数
inline int square(int ret) { return ret * ret; }
int m1() {
  double a, b;
  double c = 13.0;
  a = square(5.0);
  b = square(4.5 + 7.5);

  cout << "a = " << a << endl;
  cout << "b = " << b << endl;
  cout << "c = " << square(c++) << endl;
  cout << "Now c =" << c << endl;

  return 0;
}

double cube(double x) {
  x = x * x;
  return x;
}
double recube(double &x) {
  x = x * x;
  return x;
}
int m2() {
  double x = 3.0;
  cout << cube(x);
  cout << " = cube of " << x << endl;
  cout << recube(x);
  cout << " = cube of " << x << endl;
  return 0;
}

// 8.6将引用用于结构体
struct sysop {
  char name[26];
  char quote[64];
  int used;
};
const sysop &use(sysop &ret) {
  cout << ret.name << endl;
  cout << ret.quote << endl;
  ret.used++;
  return ret;
}
int m3() {
  sysop looper = {"Rick", "goto kind of guy", 0};

  use(looper);
  cout << "Looper:" << looper.used << endl;

  sysop copycat;
  copycat = use(looper);
  cout << "Looper:" << looper.used << endl;
  cout << "Copycat:" << copycat.used << endl;
  cout << "use(looper):" << use(looper).used << endl;

  return 0;
}

// 8.7:创建一个函数，将指定的字符串加入到另一个字符串前面或者后面
string version1(const string &s1, const string &s2) {
  string temp;
  temp = s2 + s1 + s2;
  return temp;
}
const string &version2(string &s1, const string &s2) {
  s1 = s2 + s1 + s2;
  return s1;
}
// const string &version3(string &s1, const string &s2) {
//   string temp;
//   temp = s2 + s1 + s2;
//   // return
//   //
//   temp;//这里的temp是一个局部变量，出了作用域就会被销毁，所以不能进行引用返回。
// }
int m4() {
  string input;
  string copy;
  string result;

  cout << "Enter a string:";
  getline(cin, input);
  copy = input;
  cout << "your string as entered:" << input << endl;
  result = version1(input, "***");
  cout << "your string enhanced:" << result << endl;
  cout << "your original string :" << input << endl;

  result = version2(input, "###");
  cout << "your string enhanced:" << result << endl;
  cout << "your original string :" << input << endl;

  cout << "Resetting original string." << endl;
  input = copy;
  // result = version3(input, "@@@");
  cout << "your string enhanced:" << result << endl;
  cout << "your original string:" << input << endl;

  return 0;
}

// 8.8：
const int limit = 5;
void file_it(ostream &os, double fo, const double fe[], int n) {
  ios_base::fmtflags initial;
  initial = os.setf(ios_base::fixed);
  os.precision(0);
  os << "Focal length of objective:" << fo << " mm" << endl;
  os.setf(ios::showpoint);
  os.precision(1);
  os.width(12);
  os << "f eyepiece";
  os.width(15);
  os << "magnification" << endl;
  for (int i = 0; i < n; i++) {
    os.width(12);
    os << fe[i];
    os.width(15);
    os << int(fo / fe[i] + 0.5) << endl;
  }
  os.setf(initial);
}
int m5() {
  ofstream fout;
  const char *fn = "data.txt";
  fout.open(fn);
  if (!fout.is_open()) {
    cout << "Can't open" << fn << endl;
    exit(1);
  }

  double objective;
  cin >> objective;
  double eps[limit];
  for (int i = 0; i < limit; i++) {
    cout << "Eyepiece #" << i + 1 << ": ";
    cin >> eps[i];
  }
  file_it(fout, objective, eps, limit);
  file_it(cout, objective, eps, limit);

  return 0;
}

// 8.9:默认参数
char *left(const char *str, int n = 1) {
  if (n < 0) {
    n = 0;
  }
  char *p = new char[n + 1];
  int i = 0;
  for (i = 0; i < n && str[i]; i++)
    p[i] = str[i];
  while (i <= n) {
    p[i++] = '\0';
  }

  return p;
}
int m333() {
  char sample[80];
  cout << "Enter a string" << endl;
  cin.get(sample, 80);
  char *ps = left(sample, 4);
  cout << ps << endl;
  delete[] ps;
  ps = left(sample);
  cout << ps << endl;
  delete[] ps;

  return 0;
}

// 8.11:模板的使用
// 实现只交换薪资和floor，不能交换名称
struct job {
  char name[40];
  double salary;
  int floor;
};
template <class T> void Swap(T &a, T &b) {
  T tmp;
  tmp = a;
  a = b;
  b = tmp;
}
template <class T> void Swap(T a[], T b[], int n) {
  T tmp;
  for (int i = 0; i < n; i++) {
    tmp = a[i];
    a[i] = b[i];
    b[i] = tmp;
  }
}
void Show(int a[]) {
  cout << a[0] << a[1] << "/" << a[2] << a[3] << "/";
  for (int i = 4; i < 8; i++) {
    cout << a[i];
  }
  cout << endl;
}
void Show(job &ret) {
  cout << ret.name << ":" << ret.salary << ":" << ret.floor << endl;
}
//这里的模板就是特化，它只接收job类型的数据
template <> void Swap<job>(job &j1, job &j2) {
  double t1;
  int t2;
  t1 = j1.salary;
  j1.salary = j2.salary;
  j2.salary = t1;
  t2 = j1.floor;
  j1.floor = j2.floor;
  j2.floor = t2;
}
int main() {
  int i = 10;
  int j = 20;
  cout << "i,j=" << i << "," << j << endl;
  Swap(i, j);
  cout << "Now i,j=" << i << "," << j << endl;

  double x = 24.5;
  double y = 81.7;
  cout << "x,y=" << x << "," << y << endl;
  Swap(x, y);
  cout << "Now x,y=" << x << "," << y << endl;

  int d1[8] = {0, 7, 0, 4, 1, 7, 7, 6};
  int d2[8] = {0, 6, 2, 0, 1, 9, 6, 9};
  cout << "Original arrays" << endl;
  Show(d1);
  Show(d2);
  Swap(d1, d2, 8);
  Show(d1);
  Show(d2);

  job sue = {"张三", 73000.60, 7};
  job sideny = {"李四", 78060.72, 9};
  Show(sue);
  Show(sideny);
  Swap(sue, sideny);
  Show(sue);
  Show(sideny);

  return 0;
}
